Sinkhole everything!
Hello friends!
As I've got some time on my hands I've decided to bring back my homelab into a working condition. I'm a huge fan of hosting nearly everything myself (besides mail) and so it didn't take long until I had my bind9 working with an internal zonefile for my environment.
So I quickly wrote a program to create a correlated sinkhole list.
What is a Sinkhole?
A sinkhole intercepts DNS requests and redirects them to a known location (like ::1 or anywhere else). This way, we suppress communication to known C&C servers or otherwise malicious sites.
If you want to learn more about sinkholes, use this resource: SANS - DNS Sinkhole
Misc infromation
Building a DNS infrastructure
Installing & configuring the requirements
Installing bind is as easy as running the following command:
apt install bind9
The configuration is also straight forward:
/etc/bind/named.conf.options
options {
directory "/var/cache/bind";
allow-transfer {"none";};
allow-recursion {10.0.0.0/24; localhost;};
forwarders {
dns.forwarder.ofyour.choosing; // 8.8.8.8 for example
};
dnssec-validation auto;
listen-on-v6 { any; };
};
For the purpose of sinkholing certain domains we add another entry in the named.conf file.
/etc/bind/named.conf
include "/etc/bind/named.conf.blocklist";
You won't be able to start it right now as there is no named.conf.blocklist.
Internal Zones
I'm using a non-routeable (well not really it's dns) inside my LAN for stuff like Gollum, Gogs and other services.
So the zonefile looks basically like this:
$TTL 604800
@ IN SOA localhost. admin.localhost. (
2 ; Serial
604800 ; Refresh
86400 ; Retry
2419200 ; Expire
604800 ) ; Negative Cache TTL
@ IN NS localhost.
@ IN A x.x.x.x
vault IN A x.x.x.x
cc IN A x.x.x.x
git IN A x.x.x.x
wiki IN A x.x.x.x
And the entry in the named config:
zone "internal.uauth.io" {
type master;
file "/etc/bind/internal.uauth.io";
};
Sinkhole
Introducing Blocker
While it's not the most elegant solution it does it's job of correlating different blocklists into one coherent zonedefinition.
Installation
As we use curl underneath, we need to install the dependencies for the hooks:
apt install libssl-dev pkg-config
Create the config folder and copy the config from the repository.
mkdir /etc/blocker
mv config.yml /etc/blocker
Configuration
My main config looks like this:
named_path: /etc/bind/named.conf.blocklist
path: /etc/bind/blocker/
sinkhole: 127.0.0.1
sinkhole6: ::1
reset: true
blocklists:
- 20min.ch
onlinelists:
- https://raw.githubusercontent.com/davidonzo/Threat-Intel/master/lists/latestdomains.txt
- https://raw.githubusercontent.com/nextdns/cname-cloaking-blocklist/master/domains
- https://v.firebog.net/hosts/static/w3kbl.txt
- https://v.firebog.net/hosts/Admiral.txt
- https://adaway.org/hosts.txt
- https://orca.pet/notonmyshift/hosts.txt
- https://hostfiles.frogeye.fr/firstparty-trackers-hosts.txt
- https://gitlab.com/curben/urlhaus-filter/-/raw/master/urlhaus-filter-hosts.txt
- https://raw.githubusercontent.com/hoshsadiq/adblock-nocoin-list/master/hosts.txt
- https://raw.githubusercontent.com/bongochong/CombinedPrivacyBlockLists/master/newhosts-final.hosts
Running
Just execute the binary which you can download from the release page on the repository.
crontab for automation
0 3 * * * /usr/local/bin/binder
Stats
Entries
With all the lists I have around 472 634 domains sinkholed.
This doesn't comes without sacrifices. While my bind9 server beforehand needed around 128MB to work properly (lol), it requires now around 4GB. The list gets purged every night and replaced with a fresh one.
Zonefile
The zonefile initself is nothing special
/etc/bind/blocker/blocker.zone
$TTL 604800
@ IN SOA localhost. admin.localhost. (
1
3H
15M
1W
1D
);
IN NS localhost.
IN A 127.0.0.1
IN TXT 127.0.0.1
IN AAAA ::1
We redirect all NS, A(ipv4), AAAA (ipv6) an TXT requests to 127.0.0.1/::1. All the domains get listed in the named.conf.blocklist.
/etc/bind/named.conf.blocklist
zone "0-24bpautomentes.hu"{
type master;
file "/etc/bind/blocker/blocker.zone";
check-names ignore;
};
zone "0-day.us"{
type master;
file "/etc/bind/blocker/blocker.zone";
check-names ignore;
};
Conclusion
Would it have been easier to write it in python?
ofc but where's the fun in there?
Does it work?
uauth@hakase:/etc/bind$ ping ads.youtube.com
PING ads.youtube.com(localhost (::1)) 56 data bytes
64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.026 ms